#include "EmailManagerSingleton.h"
#include "SettingsManagerSingleton.h"

//================================================
QSharedPointer<EmailManagerSingleton> EmailManagerSingleton::instance;
//================================================
EmailManagerSingleton *EmailManagerSingleton::getInstance(){
    if(EmailManagerSingleton::instance.isNull()){
        QSharedPointer<EmailManagerSingleton> localInstance(new EmailManagerSingleton);
        EmailManagerSingleton::instance = localInstance;
    }
    EmailManagerSingleton *pointer = EmailManagerSingleton::instance.data();
    return pointer;
}
//================================================
EmailManagerSingleton::EmailManagerSingleton(QObject *parent) :
    QObject(parent){
    this->smtpConnected = false;
    this->_connectSlots();
}
//================================================
void EmailManagerSingleton::_connectSlots(){
    this->connect(this->smtp.data(),
                  SIGNAL(connectionFailed(QByteArray)),
                  SIGNAL(connectionFailed(QByteArray)));
    this->connect(this->smtp.data(),
                  SIGNAL(authenticationFailed(QByteArray)),
                  SIGNAL(authenticationFailed(QByteArray)));
    this->connect(this->smtp.data(),
                  SIGNAL(mailFailed(int, int, QByteArray)),
                  SIGNAL(mailFailed(int, int, QByteArray)));
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    this->connect(settingsManager,
                  SIGNAL(emailInformationChanged()),
                  SLOT(reconnectToSmtp));
    this->connect(this->smtp.data(),
                  SIGNAL(connectionFailed(QByteArray)),
                  SLOT(onFailed(QByteArray)));
    this->connect(this->smtp.data(),
                  SIGNAL(authenticationFailed(QByteArray)),
                  SLOT(onFailed(QByteArray)));
    this->connect(this->smtp.data(),
                  SIGNAL(mailFailed(int, int, QByteArray)),
                  SLOT(onMailFailed(int, int, QByteArray)));
}
//================================================
void EmailManagerSingleton::onFailed( const QByteArray & msg ){
    this->disconnectOfSmtp();
}
//================================================
void EmailManagerSingleton::onMailFailed(int mailID, int errorCode, const QByteArray & msg){
    this->disconnectOfSmtp();
}
//================================================
bool EmailManagerSingleton::isEmailSettingsFilled(){
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    QString emailSender = settingsManager->getEmailSender();
    QString passwordSender = settingsManager->getPasswordSender();
    QString serverAddress = settingsManager->getServerAddress();
    bool settingsFilled = !emailSender.isEmpty()
                    && !passwordSender.isEmpty()
                    && !serverAddress.isEmpty();
    return settingsFilled;
}
//================================================
void EmailManagerSingleton::sendTestEmail(){
    QString title = tr("TEST MultimediaRecorder");
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QString currentDateTimeString = currentDateTime.toString();
    QString content = tr("This is an email test done on ")
                    + currentDateTimeString;
    QString imageFilePath
                    = SettingsManagerSingleton::getInstance()->getImagesTestFilePath();
    this->sendEmail(title, content, imageFilePath);
}
//================================================
void EmailManagerSingleton::sendEmail(QString title,
                                      QString content,
                                      QString imageFilePath){
    qDebug() << "void EmailManagerSingleton::sendEmail(...) called";
    SettingsManagerSingleton *settingsManager
                    = SettingsManagerSingleton::getInstance();
    QString emailSender = settingsManager->getEmailSender();
    QString emailReceivers = settingsManager->getEmailReceivers();
    QxtMailMessage email(emailSender, emailReceivers);
    email.setSubject(title);
    email.setBody(content);
    QxtMailAttachment attachment
                    = QxtMailAttachment::fromFile(imageFilePath);
    qDebug() << " Attaching: " << imageFilePath;
    email.addAttachment(imageFilePath, attachment);
    QTime currentTime = QTime::currentTime();
    int ellapstedTimeWithServerInMs
            = this->lastTimeWithServer.msecsTo(currentTime);
    qDebug() << " ellapstedTimeWithServerInMs: " << ellapstedTimeWithServerInMs;
    if(!this->smtpConnected){
        this->connectToSmtp();
    }else if(ellapstedTimeWithServerInMs > 4 * 60 * 1000){
        this->reconnectToSmtp();
    }
    this->smtp->send(email);
    this->lastTimeWithServer = QTime::currentTime();
    qDebug() << "void EmailManagerSingleton::sendEmail(...) called";
}
//================================================
void EmailManagerSingleton::reconnectToSmtp(){
    qDebug() << "void EmailManagerSingleton::reconnectToSmtp() called";
    this->disconnectOfSmtp();
    this->connectToSmtp();
    qDebug() << "void EmailManagerSingleton::reconnectToSmtp() end";
}
//================================================
void EmailManagerSingleton::disconnectOfSmtp(){
    qDebug() << "void EmailManagerSingleton::disconnectOfSmtp() called";
    if(this->smtpConnected){
        qDebug() << "Disconnecting from host";
        this->smtp->disconnectFromHost();
        this->smtp
                = QSharedPointer<QxtSmtp>(
                    NULL);
        this->smtpConnected = false;
        //QxtSmtp smtpTemp; //TODO create a new smtp + use of smart pointer
        //this->smtp = smtpTemp;
    }
    qDebug() << "void EmailManagerSingleton::disconnectOfSmtp() end";
}
//================================================
void EmailManagerSingleton::connectToSmtp(){
    qDebug() << "void EmailManagerSingleton::connectToSmtp() called";
    if(!this->smtpConnected){
        if(this->smtp.isNull()){
            this->smtp
                    = QSharedPointer<QxtSmtp>(
                        new QxtSmtp);
        }

        SettingsManagerSingleton *settingsManager
                        = SettingsManagerSingleton::getInstance();
        QString emailSender = settingsManager->getEmailSender();
        QString passwordSender = settingsManager->getPasswordSender();
        QString serverAddress = settingsManager->getServerAddress();
        bool emailSettingsFilled = this->isEmailSettingsFilled();
        if(emailSettingsFilled){
            qDebug() << "EmailManagerSingleton info ok";
            this->smtp->setUsername(emailSender.toLatin1());
            this->smtp->setPassword(passwordSender.toLatin1());
            this->smtp->connectToSecureHost(serverAddress);
            this->smtpConnected = true;
            this->lastTimeWithServer = QTime::currentTime();
        }else{
            this->smtpConnected = false;
        }
    }
    qDebug() << "void EmailManagerSingleton::connectToSmtp() end";
}
//================================================


